<?php


namespace app\shop\controller\pc;


use app\BaseController;
use app\enterprise\model\Friend;
use app\enterprise\model\GroupUser;
use app\enterprise\model\Message;
use app\enterprise\model\User;
use app\shop\model\chat\GroupUserModel;
use app\shop\model\order\OrderModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\chat\ChatService;
use app\shop\service\chat\MessageService;
use app\shop\service\config\ConfigService;
use app\shop\service\until\FileService;
use app\shop\service\until\TencentVideoService;
use app\shop\service\user\FriendService;
use app\shop\service\user\UserService;
use Exception;
use GatewayClient\Gateway;
use think\App;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;

class ImController extends BaseController
{
    protected $userInfo;
    protected $fileType = ['file', 'image', 'video', 'voice', 'emoticon'];

    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->userInfo = $this->request->middleware('userInfo');
    }

    /**
     * 获取某个部门人
     * @return \think\response\Json
     */
    public function getDepartmentList()
    {
        try {
            $userInfo = $this->request->middleware('userInfo');
            $list = FriendService::getDepartmentFriendList($userInfo);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 聊天列表
     * @return \think\response\Json
     */
    public function getContacts()
    {
        try {
            $userId = $this->request->middleware('userId');
            $userInfo = $this->request->middleware('userInfo');
            $search = $this->request->param('search', '', 'trim');
            $list = ChatService::getContactList($userInfo, $search);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }


    /**
     * 发送消息
     * @return \think\response\Json
     */
    public function sendMessage()
    {
        Db::startTrans();
        try {
            $param = $this->request->param();
            $param['user_id'] = $this->request->middleware('userId');
            $data = Message::sendMessage($param);
            Db::commit();
            return $this->success($data);
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception->getMessage());
        }
    }


    /**
     * 聊天记录-聊天框内
     * @return \think\response\Json
     */
    public function getMessageList()
    {
        try {
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            $type = $this->request->param('type', 'all', 'trim');
            $keywords = $this->request->param('keywords', '', 'trim');
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 20, 'int');
            $userInfo = $this->request->middleware('userInfo');

            $messageService = new MessageService();
            $list = $messageService->getMessageList($userInfo, $chatSign, $type, $keywords, $page, $limit);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 聊天记录-历史消息
     * @return \think\response\Json
     */
    public function getMessageRecord()
    {
        try {
            $upPage = $this->request->param('up_page', 1, 'int');
            $downPage = $this->request->param('down_page', 1, 'int');
            $listRows = $this->request->param('limit', 10, 'int');
            $isFirst = $this->request->param('is_first', 1, 'int');
            $msgId = $this->request->param('msg_id', 0, 'int');
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            $search = $this->request->param('search', '', 'trim');
            // 0下拉加载以前的消息 1上拉加载以后的消息
            $directional = $this->request->param('directional', 1, 'int');

            $isRead = $this->request->param('is_read', 0, 'int');
            $type = $this->request->param('type', 'all', 'trim');
            $userInfo = $this->request->middleware('userInfo');

            $messageService = new MessageService();
            $list = $messageService->getMessageRecord($msgId, $userInfo, $chatSign, $listRows, $isFirst, $directional, $upPage, $downPage, $search, $isRead, $type);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }


    // 设置当前窗口的消息默认为已读
    public function setMsgIsRead()
    {
        $chatSign = $this->request->param('chat_sign', '', 'trim');
        $userId = $this->request->middleware('userId');
        $chatInfo = GroupUserModel::where('chat_sign', $chatSign)->where('user_id', $userId)->find();
        if (!$chatInfo) {
            return $this->success();
        }
        $chatInfo->unread = 0;
        $chatInfo->save();
        return $this->success('');
    }

    /**
     * 语音电话
     * @return \think\response\Json
     */
    public function sendToMsg()
    {
        try {
            $chatSign = $this->request->param('chat_sign', 0, 'int');
            $status = $this->request->param('status', '', 'trim');
            $event = $this->request->param('event', 'calling', 'trim');
            $sdp = $this->request->param('sdp', '', 'trim');
            $iceCandidate = $this->request->param('iceCandidate', '', 'trim');
            $msg_id = $this->request->param('msg_id', '', 'trim');
            $id = $this->request->param('id', '', 'trim');
            $code = $this->request->param('code', 901, 'int');
            $orderId = $this->request->param('order_id', 0, 'int');
            $userInfo = $this->userInfo;
            $fromUserId = $this->userInfo['user_id'];
            $type = 0;
            if ($event == 'calling') {
                $status = 3;
            }
            // 如果该用户不在线，则发送忙线
            Gateway::$registerAddress = config('gateway.registerAddress');
            // 对方是否正在和别人通话中
            $chat_identify = chat_identify($userInfo['user_id'], $toContactId);
            $chatSign = generate_chat_sign($userInfo['user_id'], $toContactId, $orderId);
            if (!Gateway::isUidOnline($toContactId)) {
                $fromUserId = $toContactId;
                $toContactId = $this->userInfo['user_id'];
                $code = 907;
                $event = 'busy';
            }
            $callTime = time();
            if ($code == 906) {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $startTime = $message['call_start_time'];
                $diffTime = time() - $startTime;
                $minutes = floor($diffTime / 60);
                $seconds = $diffTime % 60;
                $callTime = sprintf('%d:%d', $minutes, $seconds);
            }
            switch ($code) {
                case 902:
                    $content = '已取消通话';
                    break;
                case 903:
                    $content = '已拒绝';
                    break;
                case 905:
                    $content = '未接通';
                    break;
                case 906:
                    $content = '通话时长 ' . $callTime;
                    break;
                case 907:
                    $content = '忙线中';
                    break;
                case 908:
                    $content = '其他端已操作';
                    break;
                default:
                    $content = $type == 1 ? '视频通话' : '语音通话';
                    break;
            }
            switch ($event) {
                case 'calling':
                    $content = $type == 1 ? '视频通话' : '语音通话';
                    break;
                case 'acceptRtc':
                    $content = '接听通话请求';
                    break;
                case 'iceCandidate':
                    $content = '数据交换中';
                    break;
                case 'busy':
                    $content = '忙线中';
                    break;
            }
            $fromUserInfo = UserModel::field('user_id,mobile,realname,avatar')->where('user_id', $fromUserId)->find();
            $toUserInfo1 = UserModel::field('user_id,mobile,realname,avatar,role_id')->where('user_id', $toContactId)->find();
            $data = [
                'id' => $id,
                'order_id' => $orderId,
                'msg_id' => $msg_id,
                'sendTime' => time() * 1000,
                'toContactId' => $toContactId,
                'content' => $content,
                'type' => 'webrtc',
                'status' => 'succeed',
                'is_group' => 0,
                'is_read' => 0,
                'from_user' => $fromUserId,
                'fromUser' => $fromUserInfo,
                'toUser' => $toUserInfo1,
                'at' => [],
                'chat_sign' => $chatSign,
                'extends' => [
                    'type' => $type,    //通话类型，1视频，0语音。
                    'status' => $status, //，1拨打方，2接听方
                    'event' => $event,
                    'callTime' => $callTime,
                    'sdp' => $sdp,
                    'code' => $code,  //通话状态:呼叫901，取消902，拒绝903，接听904，未接通905，接通后挂断906，忙线907,其他端操作908
                    'iceCandidate' => $iceCandidate,
                    'isMobile' => $this->request->isMobile() ? 1 : 0,
                ]
            ];
            if ($event == 'calling') {
                if ($code == 901) {
                    $callStatus = 1;
                } else {
                    $callStatus = 0;
                }
                $msg = [
                    'from_user' => $userInfo['user_id'],
                    'from_user_role_id' => $userInfo['role_id'],
                    'to_user' => $toContactId,
                    'to_user_role_id' => $toUserInfo1['role_id'],
                    'id' => $id,
                    'content' => str_encipher($content),
                    'chat_identify' => $chat_identify,
                    'chat_sign' => $chatSign,
                    'create_time' => time(),
                    'type' => $data['type'],
                    'is_group' => 0,
                    'order_id' => $orderId,
                    'is_read' => 0,
                    'extends' => $data['extends'],
                    'call_status' => $callStatus,
                    'call_start_time' => time(),
                    'chat_user' => $fromUserId . ',' . $toContactId . ',',
                ];
                $message = new Message();
                $message->update(['is_last' => 0], ['chat_identify' => $chat_identify]);
                $message->save($msg);
                $msg_id = $message->msg_id;
                $data['msg_id'] = $msg_id;
                // 将接收人设置为发送人才能定位到该消息
                $data['toContactId'] = $userInfo['user_id'];
                $data['call_status'] = 1;
            } elseif ($event == 'hangup') {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $message->content = str_encipher($content);
                $extends = $message->extends;
                $extends['code'] = $code;
                $message->extends = $extends;
                $message->call_status = 0;
                $message->call_end_time = time();
                $message->save();
                $data['call_status'] = 0;
                $data['call_end_time'] = time();
                $data['msg_id'] = $message->msg_id;
            } elseif ($event == 'acceptRtc') {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $message->call_status = 2;
                $message->save();
                $data['call_status'] = 2;
                $data['msg_id'] = $message->msg_id;
            }
            $data['quote'] = new \stdClass();
            wsSendMsg($toContactId, 'webrtc', $data);
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage() . $exception->getLine());
        }
    }

    /**
     * 腾讯语音签名
     * @return \think\response\Json
     */
    public function getUserSign()
    {
        try {
            $appId = env('tencent.appid');
            $key = env('tencent.key');
            $userId = $this->request->middleware('userId');
            $tencentVideoService = new TencentVideoService($appId, $key);
            $sign = $tencentVideoService->genUserSig($userId);
            return $this->success($sign);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    // 撤回消息
    public function undoMessage()
    {
        try {
            $id = $this->request->param('id');
            $message = Message::where(['id' => $id])->find();
            if (!$message) {
                throw new \Exception('消息不存在');
            }
            // 如果时间超过了2分钟也不能撤回
            $createTime = is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time'];
            if (time() - $createTime > 120 && $message['is_group'] == 0) {
                throw new \Exception('超过2分钟不能撤回！');
            }
            $text = "撤回了一条消息";
            $fromUserName = "对方";
            $toContactId = $message['to_user'];
            $message->content = str_encipher($text);
            $message->type = 'event';
            $message->is_undo = 1;
            $message->save();
            $info = $message->toArray();
            // $data = $info;
            $data['content'] = $fromUserName . $text;
            $data['sendTime'] = $createTime * 1000;
            $data['id'] = $info['id'];
            $data['from_user'] = $info['from_user'];
            $data['msg_id'] = $info['msg_id'];
            $data['status'] = $info['status'];
            $data['type'] = 'event';
            $data['isMobile'] = $this->request->isMobile() ? 1 : 0;
            wsSendMsg($toContactId, 'undoMessage', $data, $info['is_group']);
            if ($info['is_group'] == 0) {
                // 给自己也发一份推送，多端同步
                $data['content'] = "你" . $text;
                wsSendMsg($this->userInfo['user_id'], 'undoMessage', $data, $info['is_group']);
            }
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }
}